#include <myhead.h>
#include <pthread.h>
#include "tool.h"
extern sem_t sem_for_list;
extern int msgid;
extern int semid;
int sockfd = 0;

void signal_handler(int sig)
{ // 先申请的后释放 避免先申请的是后申请的先决条件
    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
    // 删除信号灯
    semctl(semid, 0, IPC_RMID);
    // 删除信号量
    sem_destroy(&sem_for_list);
    // 销毁链表
    // list_free(&head);
    // 关闭套接字
    close(sockfd);
    exit(0);
}

int main(int argc, char const *argv[])
{
    /*demo2*/
    if (2 != argc)
    {
        printf("Usage: %s <port>\n", argv[0]);
        return -1;
    }
    create_daemon(); // 创建守护进程
    if (-1 == (sockfd = net_init(argv[1]))) // 网络初始化
    {
        printf("net_init failed\n");
        return -1;
    }
    list_t *head = NULL;
    if (list_create(&head)) // 链表初始化
    {
        printf("list_create failed\n");
        goto END1;
    }
    sem_init(&sem_for_list, 0, 1); // 信号量初始化
    if (mysemlamp_init())          // 信号灯初始化
    {
        printf("mysem_init failed\n");
        goto END3;
    }
    if (-1 == msg_queue_init()) // 消息队列初始化
    {
        printf("msg_queue_init failed\n");
        goto END4;
    }

    pthread_t heartbeat_tid;
    pthread_t msg_tid;
    pthread_create(&heartbeat_tid, NULL, heartbeat_thread, (void *)head); // 创建线程, 遍历链表
    pthread_detach(heartbeat_tid);                                        // 分离线程
    pthread_create(&msg_tid, NULL, monitor_hw_thread, NULL);              // 创建线程, 消息队列
    pthread_detach(msg_tid);                                              // 分离线程

    if (signal(SIGINT, signal_handler) == SIG_ERR)
    {
        perror("Failed to set signal handler");
        goto END5;
    }

    printf("server is running...\n");
    while (1)
    {
        int connect_fd = accept(sockfd, NULL, NULL);
        if (-1 == connect_fd)
        {
            perror("accept error");
            continue;
        }
        printf("有下位机连接\n");
        pthread_t handle_tid;
        pthread_create(&handle_tid, NULL, handle_thread, (void *)(long)connect_fd); // 不加(long)也没事 加了代码更清晰
        pthread_detach(handle_tid);
    }

END5:
    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
END4:
    // 删除信号灯
    semctl(semid, 0, IPC_RMID);
END3:
    // 删除信号量
    sem_destroy(&sem_for_list);
END2:
    // 销毁链表
    list_free(&head);
END1:
    // 关闭套接字
    close(sockfd);
    return 0;
}